package com.ng.framework.view.desktop;

import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;

import com.ng.framework.persistence.NGGenericPersistence;

public abstract class NGEditDialog<T, P extends NGGenericPersistence<T>> extends JDialog implements ActionListener {

	private static final long serialVersionUID = 5878330170740525715L;

	private P persitence;
	private T instance;

	private boolean creationMode;
	private NGEntitySelectorField<T,P> entitySelection;

	private JPanel detailPanel;
	private JButton saveButton;
	private JButton cancelButton;

	public NGEditDialog(final Window owner, final P persistence, final T instance) {
		super(owner);
		
		this.setModal(true);

		this.instance = instance;
		this.persitence = persistence;

		this.creationMode = instance == null;

		this.initComponents();

		this.buildGui();

		if (!creationMode) {
			this.populateDetailPanel(instance);
		}
	}
	
	public NGEditDialog(final Window owner, final P persistence, final T instance, NGEntitySelectorField<T,P> entitySelection) {
		this(owner,persistence,instance);
		this.entitySelection = entitySelection;
		
	}

	public NGEditDialog(final Frame owner, final P persistence, final T instance, NGEntitySelectorField<T,P> entitySelection) {
		this(owner,persistence,instance);
		this.entitySelection = entitySelection;
		
	}


	private void initComponents() {

		this.detailPanel = this.createDetailPanel();

		this.saveButton = NGGUIUtils.createTextButton("Guardar", this);
		this.cancelButton = NGGUIUtils.createTextButton("Cancelar", this);
	}

	protected abstract JPanel createDetailPanel();

	private void buildGui() {
		this.setLayout(new GridBagLayout());

		this.add(detailPanel, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
				new Insets(5, 5, 5, 5), 0, 0));
		this.add(this.createButtonsPanel(), new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.CENTER,
				GridBagConstraints.HORIZONTAL, new Insets(0, 5, 5, 0), 0, 0));
	}

	private JPanel createButtonsPanel() {
		final JPanel buttonsPanel = new JPanel(new GridBagLayout());

		buttonsPanel.add(saveButton, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.EAST, GridBagConstraints.NONE,
				new Insets(0, 0, 0, 5), 0, 0));
		buttonsPanel.add(cancelButton, new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.NONE,
				new Insets(0, 0, 0, 0), 0, 0));

		return buttonsPanel;
	}

	protected abstract void populateDetailPanel(T instance);

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == saveButton) {
			if (this.validateInput()) {
				if (instance == null) {
					instance = createNewInstance();
				}

				populateInstance(instance);

				if (creationMode) {
					persitence.create(instance);
				} else {
					persitence.update(instance);
				}

				if (entitySelection != null) {
					entitySelection.setEntity(instance);
				}
				this.dispose();
			}
		} else if (e.getSource() == cancelButton) {
			this.dispose();
		}
	}

	protected abstract boolean validateInput();

	protected abstract T createNewInstance();

	protected abstract void populateInstance(T instance);

	public boolean isCreationMode() {
		return creationMode;
	}

}
